//
//  HMStatusDAL.swift
//  WeiBoSwift
//
//  Created by hgj on 2016/11/27.
//  Copyright © 2016年 HuGuoJian. All rights reserved.
//  微软提出的一种概念 数据访问层

import UIKit

class HMStatusDAL: NSObject {

    //1.检查本地是否有缓存数据
    
    //2. 如果本地有缓存数据 就直接返回本地的缓存数据,给用户节省流量,让用户在没有网络的情况可以浏览之前的内容
    
    //3. 没有缓存数据就请求网络数据 返回网络数据
    
    //4. 获取网络数据之后就应该立即存储网络数据

    // 检查本地数据
    class func  checkoutStatus(sinceId: Int64, maxId: Int64) -> [[String : Any]]? {
        // 在数据库中userId 是主键
        guard let userId = HMUserAccountViewModel.shared.userInfo?.uid else {
            return nil
        }
        
        var sql = "SELECT status FROM T_Status WHERE userId = \(userId)"
        
        if sinceId > 0 {
            sql += "AND statusId > \(sinceId)"
        }
        
        if maxId > 0 {
            sql += "AND statusId < \(maxId)"
        }
        
        sql += "ORDER BY statusId DESC"
        
        sql += "LIMIT 100"
        
        // 实例化数据
        var array = [[String : Any]]()
        
        HMSQliteTools.shared.queue.inDatabase { (db) in
            
            guard let res = db?.executeQuery(sql, withArgumentsIn: nil) else {
                return
            }
            
            // 逐条获取数据
            while res.next() {
                // 获取二进制数据
                let jsonData = res.data(forColumn: "status")
                
                // 转换成json字典 数据转换的错误处理机制
                let dict = try! JSONSerialization.jsonObject(with: jsonData!, options: [])
                array.append(dict as! [String : Any])
            }
        }
        
        return array
    }
    
    // 类方法加载数据
    class func  loadHomeData(sinceId: Int64, maxId: Int64, finished: @escaping([[String : Any]]?) -> ()) {
        
        let res = checkoutStatus(sinceId: sinceId, maxId: maxId)
        
        // 可以写多个表达式,但是后面的没有提示
        if let result = res, result.count > 0 {
            
            // 有缓存的情况下回调数据
            finished(result)
            return
        }
        
        // 没有缓存数据.请求网络数据
        //没有缓存数据, 请求网络数据
        let urlString = "https://api.weibo.com/2/statuses/home_timeline.json"
        let parameters = ["access_token" : HMUserAccountViewModel.shared.access_token,
                          "max_id" : "\(maxId)",
            "since_id" : "\(sinceId)"]
        
        HMNetworkTools.shared.request(method: .GET, urlString: urlString, parameters: parameters, finished: { (responseObject,error) -> () in
            if error != nil {
                //告诉外界请求失败 在闭包中如何完成失败的回调
                //TODO: 完成失败的回调
                finished(nil)
                return
            }
            
            //成功
            let dict = responseObject as! [String : Any]
            //尝试转换为字典类型的数组
            guard let array = dict["statuses"] as? [[String : Any]] else {
                finished(nil)
                return
            }
            
            
            //回调的网络 请求的结果
            finished(array)
            //存储到本地
            cacheStautus(array: array)
        })
    }
    
    // 存储数据
    class func cacheStautus(array: [[String :Any]]) {
        // 主键
        guard let userId = HMUserAccountViewModel.shared.userInfo?.uid else {
            return
        }
        
        let sql = "INSERT OR REPLACE INTO T_Status (statusId,status,userId) VALUES (?,?,?)"
        HMSQliteTools.shared.queue.inTransaction { (db, rollback) in
            for item in array {
                let statusId = item["id"]
                let jsonData = try! JSONSerialization.data(withJSONObject: item, options: [])
                let res = db!.executeUpdate(sql, withArgumentsIn: [statusId,jsonData,userId])
                
                if !res {
                    //不成功就回滚
                    rollback?.pointee = true
                    return
                }
            }
        }
    }
}
